import java.sql.Connection;

public abstract class AccountManager {

	private Connection connection;
	private PropertyDBManager propertyDBManager;
	private RankDBManager rankDBManager;
	private BalanceDBManager balanceDBManager;

	public AccountManager(Connection initConnection, PropertyDBManager propertyDBManager, RankDBManager rankDBManager, BalanceDBManager balanceDBManager) {
		// constructor - initialiaze connection
		// use this connection in all functions of AccountManager

		setConnection(initConnection);
		setPropertyDBManager(propertyDBManager);
		setRankDBManager(rankDBManager);
		setBalanceDBManager(balanceDBManager);
	}

	public Connection getConnection() {
		return connection;
	}

	public void setConnection(Connection connection) {
		this.connection = connection;
	}

	public abstract boolean addAccount(Account newAccount) throws DBManagerException;

	// Add new account to Account table
	// function receive Account object, propertyDBManager,rankDBManager
	// return TRUE - in case account was successfuly added to table
	// return FALSE , with appropriate message in case can't add account

	public abstract boolean deleteAccount(Account oldAccount) throws DBManagerException;

	// Delete old account from Account table
	// function receive Account object
	// return TRUE - in case account was successfuly deleted from the table
	// return FALSE , with appropriate message in case can't delete account

	public abstract boolean depositWithComm(Account currAccount, double moneyAmount) throws DBManagerException;

	// Add money to current account (with commission)
	// function receive Account object and moneyAmount we want to add
	// return TRUE - in case money was successfuly added to current account
	// return FALSE , with appropriate message in case can't add money to this
	// account

	public abstract boolean depositWithoutComm(Account currAccount, double moneyAmount) throws DBManagerException;

	// Add money to current account (without commission)
	// function receive Account object and moneyAmount we want to add
	// return TRUE - in case money was successfuly added to current account
	// return FALSE , with appropriate message in case can't add money to this
	// account

	public abstract boolean withdrawWithComm(Account currAccount, double moneyAmount) throws DBManagerException;

	// withdraw money from current account with commission
	// function receive Account object and moneyAmount we want to get
	// return TRUE - in case money was successfuly withdraw from current account
	// return FALSE , with appropriate message in case can't withdraw money from
	// this account

	public abstract boolean withdrawWithoutComm(Account currAccount, double moneyAmount) throws DBManagerException;

	// withdraw money from current account without commission (for deposit)
	// function receive Account object and moneyAmount we want to get
	// return TRUE - in case money was successfuly withdraw from current account
	// return FALSE , with appropriate message in case can't withdraw money from
	// this account

	public abstract Account getAccountById(long currAccountId) throws DBManagerException;

	// get Account object by his ID
	// function receive current account Id number
	// return appropriate Account object

	public void showAccount(Account currAccount) {
		// print data for current Account
		currAccount.PrintAccount();
	}

	public double calculateComission(Account currAccount, double moneyAmount) {
		// calculate comission for current account
		// function receive Account object and moneyAmount for account
		// operations ( deposit / withdraw money )
		// return calculate comission or 0 in case can't calculate it

		double currComission = 0;

		if ((currAccount.getCommission() > 0) & (moneyAmount > 0)) {

			currComission = (currAccount.getCommission() * moneyAmount) / 100;

		}

		return currComission;

	}

	public void setPropertyDBManager(PropertyDBManager propertyDBManager) {
		this.propertyDBManager = propertyDBManager;
	}

	public PropertyDBManager getPropertyDBManager() {
		return propertyDBManager;
	}

	public void setRankDBManager(RankDBManager rankDBManager) {
		this.rankDBManager = rankDBManager;
	}

	public RankDBManager getRankDBManager() {
		return rankDBManager;
	}

	public void setBalanceDBManager(BalanceDBManager balanceDBManager) {
		this.balanceDBManager = balanceDBManager;
	}

	public BalanceDBManager getBalanceDBManager() {
		return balanceDBManager;
	}

}
